gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFButton.cpp

    // SWFButton.cpp: implementation of the CSWFButton class.
//
//////////////////////////////////////////////////////////////////////

#include "SWFButton.h"


CSWFButton::CSWFButton(USHORT nID, USHORT depth, bool bMenuButton)
{
	// Init members
	m_ObjectType = SWF_OBJECT_TYPE_BUTTON;
	memset(&m_Button, 0, sizeof(SWF_DEFINE_BUTTON2_TAG));
	m_Button.Header.TagCodeAndLength = (34 << 6) | 0x003F;
	m_Button.ButtonID = nID;
	if (bMenuButton)
		m_Button.Flags = 0x01;
	m_Button.ActionOffset = 0;
	m_Button.Characters = NULL;
	m_NumberButtonRecords = 0;
	m_ID = nID;
	m_Depth = depth;
	m_NumberCondActions = 0;
	m_ButtonCondActions = NULL;
	m_SWFStream = NULL;
	m_SWFStreamLength = 0;
}

CSWFButton::~CSWFButton()
{
	if (m_SWFStream != NULL)
	{
		free(m_SWFStream);
		m_SWFStream = NULL;
	}

	if (m_Button.Characters)
	{
		free(m_Button.Characters);
		m_Button.Characters = NULL;
	}

	if (m_ButtonCondActions != NULL)
	{
		for (int i=0; i<m_NumberCondActions; i++)
		{
			free(m_ButtonCondActions[i].Actions);
			m_ButtonCondActions[i].Actions = NULL;
		}

		free(m_ButtonCondActions);
		m_ButtonCondActions = NULL;
	}
}

void CSWFButton::AddStateCharacter(UCHAR stateFlags, USHORT characterID, int depth, SWF_COLOR_TRANSFORM* pColorTransform)
{
	SWF_BUTTONRECORD newButtonRecord;
	memset(&newButtonRecord, 0, sizeof(SWF_BUTTONRECORD));
	newButtonRecord.Flags = 0x0F & stateFlags;
	newButtonRecord.CharacterID = characterID;
	newButtonRecord.PlaceDepth = (USHORT)depth;
	if (pColorTransform != NULL)
	{
		newButtonRecord.bHasColorTransform = true;
		memcpy(&newButtonRecord.ColorTransform, pColorTransform, sizeof(SWF_COLOR_TRANSFORM));
	}
	else
		newButtonRecord.bHasColorTransform = false;

	// Add new ButtonRecord to the ButtonRecordArray
	m_NumberButtonRecords++;
	if (m_Button.Characters == NULL)
		m_Button.Characters = (SWF_BUTTONRECORD*)malloc(sizeof(SWF_BUTTONRECORD));
	else
		m_Button.Characters = (SWF_BUTTONRECORD*)realloc(m_Button.Characters, m_NumberButtonRecords*sizeof(SWF_BUTTONRECORD));
	memcpy(&m_Button.Characters[m_NumberButtonRecords-1], &newButtonRecord, sizeof(SWF_BUTTONRECORD));
}

void CSWFButton::AddStateAction(UCHAR flags1, UCHAR flags2, CSWFAction* pAction)
{
	UCHAR* pActionBuffer = NULL;
	int actionBufferLength = 0;

	// Calculate ActionArray length
	if (pAction != NULL)
	{
		if (pAction->IsButtonAction())
		{
			pActionBuffer = pAction->BuildSWFStream();
			actionBufferLength = pAction->GetSWFStreamLength();
		}
	}

	// Create new BUTTONCONDACTION entry
	SWF_BUTTONCONDACTION_TAG newButtonCondActionRecord;
	memset(&newButtonCondActionRecord, 0, sizeof(SWF_BUTTONCONDACTION_TAG));
	newButtonCondActionRecord.Flags1 = flags1;
	newButtonCondActionRecord.Flags2 = flags2;
	if (m_NumberCondActions > 0)
	{
		newButtonCondActionRecord.CondActionSize = sizeof(USHORT) + actionBufferLength + 2*sizeof(UCHAR);

		// Update ButtonCondActionArray
		for (int j=0; j<m_NumberCondActions; j++)
			m_ButtonCondActions[j].CondActionSize = sizeof(USHORT) + m_ButtonCondActions[j].ActionsLength + 2*sizeof(UCHAR);
	}

	// Add new ButtonCondAction entry to the ButtonCondActionArray
	m_NumberCondActions++;
	if (m_ButtonCondActions == NULL)
		m_ButtonCondActions = (SWF_BUTTONCONDACTION_TAG*)malloc(sizeof(SWF_BUTTONCONDACTION_TAG));
	else
		m_ButtonCondActions = (SWF_BUTTONCONDACTION_TAG*)realloc(m_ButtonCondActions, m_NumberCondActions*sizeof(SWF_BUTTONCONDACTION_TAG));
	memcpy(&m_ButtonCondActions[m_NumberCondActions-1], &newButtonCondActionRecord, sizeof(SWF_BUTTONCONDACTION_TAG));
	if (actionBufferLength != 0)
	{
		m_ButtonCondActions[m_NumberCondActions-1].Actions = (UCHAR*)malloc(actionBufferLength*sizeof(UCHAR));
		memcpy(m_ButtonCondActions[m_NumberCondActions-1].Actions, pActionBuffer, actionBufferLength);
		m_ButtonCondActions[m_NumberCondActions-1].ActionsLength = actionBufferLength;
	}
}

UCHAR* CSWFButton::BuildSWFStream()
{
	int i, j;

	// Calculate ButtonRecordArray size
	int buttonRecordLength = 0;
	for (i=0; i<m_NumberButtonRecords; i++)
	{
		buttonRecordLength += sizeof(UCHAR);			// Size of flags bit-field
		buttonRecordLength += sizeof(USHORT);			// Size of characterID bit-field
		buttonRecordLength += sizeof(USHORT);			// Size of PlaceDepth bit-field

		CSWFColorTransform colorTransform(&m_Button.Characters[i].ColorTransform);
		colorTransform.BuildSWFStream();
		CSWFMatrix matrixTransform;
		matrixTransform.SetMatrix(m_Button.Characters[i].PlaceMatrix);
		matrixTransform.BuildSWFStream();
		buttonRecordLength += matrixTransform.GetSWFStreamLength();	// Size of PlaceMatrix bit-field
		if (m_Button.Characters[i].bHasColorTransform)
			buttonRecordLength += colorTransform.GetSWFStreamLength();	// Size of ColorTransform bit-field
		else
			buttonRecordLength += sizeof(UCHAR);
	}

	// Calculate ButtonCondActionArray size
	int buttonCondActionLength = 0;
	for (j=0; j<m_NumberCondActions; j++)
	{
		buttonCondActionLength += sizeof(USHORT);							// Size of CondActionSize bit-field
		buttonCondActionLength += sizeof(UCHAR);							// Size of Flags1 bit-field
		buttonCondActionLength += sizeof(UCHAR);							// Size of Flags2 bit-field
		buttonCondActionLength += m_ButtonCondActions[j].ActionsLength;		// Size of Actions bit-field
	}
	if (buttonCondActionLength != 0)
		buttonCondActionLength += sizeof(USHORT);							// Size of last ButtonCondAction entry
	
	// Write DefineButton2 tag
	int newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG) + sizeof(USHORT) + sizeof(UCHAR) + sizeof(USHORT) + buttonRecordLength + sizeof(UCHAR) + buttonCondActionLength;
	m_SWFStream = (UCHAR*)malloc(newLength*sizeof(UCHAR));
	memset(m_SWFStream, 0, newLength);

	// Write button header
	m_Button.Header.Length = newLength - sizeof(SWF_RECORDHEADER_LONG);
	newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG) + sizeof(USHORT) + sizeof(UCHAR) + sizeof(USHORT);
	memcpy(m_SWFStream, &m_Button.Header, sizeof(SWF_RECORDHEADER_LONG));
	memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG), &m_Button.ButtonID, sizeof(USHORT));
	memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG)+sizeof(USHORT), &m_Button.Flags, sizeof(UCHAR));
	if (buttonCondActionLength != 0)
		m_Button.ActionOffset = sizeof(USHORT) + buttonRecordLength + sizeof(UCHAR);
	memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG)+sizeof(USHORT)+sizeof(UCHAR), &m_Button.ActionOffset, sizeof(USHORT));
	m_SWFStreamLength = newLength;

	// Write ButtonRecordArray
	for (i=0; i<m_NumberButtonRecords; i++)
	{
		CSWFColorTransform colorTransform(&m_Button.Characters[i].ColorTransform);
		UCHAR* pColorBuffer = colorTransform.BuildSWFStream();

		CSWFMatrix matrixTransform;
		matrixTransform.SetMatrix(m_Button.Characters[i].PlaceMatrix);
		UCHAR* pMatrixBuffer = matrixTransform.BuildSWFStream();

		newLength = m_SWFStreamLength + sizeof(UCHAR) + 2*sizeof(USHORT) + matrixTransform.GetSWFStreamLength();
		if (m_Button.Characters[i].bHasColorTransform)
			newLength += colorTransform.GetSWFStreamLength();
		else
			newLength += sizeof(UCHAR);
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Button.Characters[i].Flags, sizeof(UCHAR));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR), &m_Button.Characters[i].CharacterID, sizeof(USHORT));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+sizeof(USHORT), &m_Button.Characters[i].PlaceDepth, sizeof(USHORT));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+2*sizeof(USHORT), pMatrixBuffer, matrixTransform.GetSWFStreamLength());
		if (m_Button.Characters[i].bHasColorTransform)
			memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+2*sizeof(USHORT)+matrixTransform.GetSWFStreamLength(), pColorBuffer, colorTransform.GetSWFStreamLength());
		else
		{
			UCHAR color = 0x00;
			memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+2*sizeof(USHORT)+matrixTransform.GetSWFStreamLength(), &color, sizeof(UCHAR));
		}
		m_SWFStreamLength = newLength;
	}

	// Write CharacterEndFlag
	newLength = m_SWFStreamLength + sizeof(UCHAR);
	memcpy(m_SWFStream+m_SWFStreamLength, &m_Button.CharacterEndFlag, sizeof(UCHAR));
	m_SWFStreamLength = newLength;

	// Write ButtonCondActionarray
	for (j=0; j<m_NumberCondActions; j++)
	{
		newLength = m_SWFStreamLength + sizeof(USHORT) + sizeof(UCHAR) + sizeof(UCHAR) + m_ButtonCondActions[j].ActionsLength;
		memcpy(m_SWFStream+m_SWFStreamLength, &m_ButtonCondActions[j].CondActionSize, sizeof(USHORT));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(USHORT), &m_ButtonCondActions[j].Flags1, sizeof(UCHAR));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(USHORT)+sizeof(UCHAR), &m_ButtonCondActions[j].Flags2, sizeof(UCHAR));
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(USHORT)+2*sizeof(UCHAR), m_ButtonCondActions[j].Actions, m_ButtonCondActions[j].ActionsLength);
		m_SWFStreamLength = newLength;
	}

	if (buttonCondActionLength != 0)
	{
		// Write ButtonCondAction last entry
		newLength = m_SWFStreamLength + sizeof(USHORT);
		USHORT buttonCondActionEnd = 0x0000;
		memcpy(m_SWFStream+m_SWFStreamLength, &buttonCondActionEnd, sizeof(USHORT));
		m_SWFStreamLength = newLength;
	}

	return m_SWFStream;
}

int CSWFButton::GetSWFStreamLength()
{
	return m_SWFStreamLength;
}